import * as server_ui from "@minecraft/server-ui";
import * as server from "@minecraft/server";
import * as data_entity from "../data/entity";
import * as data_block from "../data/block";
import * as data_story from "../data/story";
import * as data_item from "../data/item";
import * as power_property from "./power_property";
import * as derived_tools from "./derived_tools";
import * as native_tools from "./native_tools";
import * as achieve_plan from "./achieve_plan";
import * as math_tools from "./math_tools";
export { Lexicon, Window, GameHelp, Trophy };
const craft = new Map();
craft.set('调试动态属性', {
    root: [],
    priority: 203,
    only: true,
    intel: [],
    code(player) {
        analysisDynamicProperty(player);
        return ReplyMessages.pursue_dynamic_property;
    }
});
craft.set('调试星尘力', {
    root: [],
    priority: 101,
    only: true,
    intel: [],
    code(player) {
        analysisRealm(player, 'stardust_energy', alterEnergy);
        return ReplyMessages.realm_energy;
    }
});
craft.set('调试虚岩矿脉', {
    root: [],
    priority: 102,
    only: true,
    intel: [],
    code(player) {
        analysisRealm(player, 'mineral_vein', alterMineral);
        return ReplyMessages.realm_mineral;
    }
});
craft.set('重新执行', {
    root: ["继续", "重复", "再来"],
    priority: 4,
    only: true,
    intel: [],
    code(player) {
        const entry = Lexicon.history.get(player.id);
        if (entry) {
            server.system.runTimeout(() => new Lexicon(player, entry), 10);
            return ReplyMessages.enact_echo;
        }
        else
            return ReplyMessages.unknown_echo;
    }
});
craft.set('调试开发者日志', {
    root: [],
    priority: 4,
    only: true,
    intel: [],
    code() {
        Lexicon.showLog = !Lexicon.showLog;
        return ReplyMessages.log_toggle;
    }
});
craft.set('发动元素攻击', {
    root: [],
    priority: 201,
    only: true,
    intel: [],
    code(player, texts) {
        analysisRuneHurt(player, texts[0]);
        return ReplyMessages.pursue_rune_hurt;
    }
});
craft.set('设置雾海裂隙', {
    root: [],
    priority: 202,
    only: true,
    intel: [],
    code(player, texts) {
        analysisFissure(player, texts);
        return ReplyMessages.pursue_fissure;
    }
});
craft.set('查询生物群系', {
    root: [],
    priority: 8,
    only: true,
    intel: [],
    code(player, texts) {
        return analysisBiome(player, texts[0]);
    }
});
craft.set('初始化世界规则', {
    root: [],
    priority: 2,
    only: true,
    intel: [],
    code() {
        server.world.setDynamicProperty('game_rules:regenerate.vacant_space_wasp_tower', true);
        server.world.setDynamicProperty('game_rules:regenerate.starlight_house', true);
        return { text: '#$^$#已重置世界规则, 部分结构可重新生成 !!\n' };
    }
});
class ReplyMessages {
    static get ask_for_task() {
        return { text: "请问需要我做些什么？" };
    }
    ;
    static get unknown_theme() {
        return { text: '#$^$#没太听懂...\n' };
    }
    ;
    static get unknown_paper() {
        return { text: '很抱歉... #$^$#好像没有你想要的资料呢...\n' };
    }
    ;
    static get obtain_paper() {
        return { text: '#$^$#为您查询到以下资料 : \n\n' };
    }
    ;
    static get unknown_biome() {
        return { text: '出错了！ #$^$#没有发现这个群系！\n' };
    }
    ;
    static get unknown_node() {
        return { text: '对不起哦, #$^$#没太明白你的意思呢...\n' };
    }
    ;
    static get unknown_echo() {
        return { text: '额... #$^$#不太记得了, 你能详细解释一下吗?\n' };
    }
    ;
    static get enact_echo() {
        return { text: '#$^$#明白 ! 正在执行中 !!\n' };
    }
    ;
    static get log_toggle() {
        return { text: '#$^$#收到, 正在切换日志状态\n' };
    }
    ;
    static get power_lack() {
        return { text: '咦, 权限不足? #$^$#暂时不能帮你执行这个操作\n' };
    }
    ;
    static get realm_mineral() {
        return { text: '收到, #$^$#将对<§s§l 虚岩矿脉 §r>施加<§q§l 律令 §r>\n' };
    }
    ;
    static get realm_energy() {
        return { text: '明白, #$^$#将对<§u§l 星尘能量 §r>施加<§q§l 律令 §r>\n' };
    }
    ;
    static get pursue_rune_hurt() {
        return { text: '好的, #$^$#正在通过<§q§l 律令 §r>释放<§5§l 符文伤害 §r>\n' };
    }
    ;
    static get pursue_dynamic_property() {
        return { text: '好的, #$^$#正在通过<§q§l 律令 §r>修改<§5§l 动态属性 §r>\n' };
    }
    ;
    static get pursue_fissure() {
        return { text: '好的, #$^$#正在通过<§q§l 律令 §r>构建<§9§l 雾海裂隙 §r>\n' };
    }
    ;
    constructor() { }
    ;
}
;
class LexiconData {
    static nameTag = '§d§l月华§r';
    static showLog = false;
    static history = new Map();
    static material = [
        ...data_item.help,
        ...data_block.help,
        ...data_story.help,
        ...data_entity.help,
        ...craft
    ];
    output = { rawtext: [] };
    constructor() { }
    ;
}
;
class Lexicon extends LexiconData {
    player;
    constructor(player, rawtext) {
        super();
        this.player = player;
        if (!rawtext.length)
            return;
        const sections = rawtext.split(/\s+/);
        if (sections.length < 2)
            sections.push(...rawtext.split(''));
        this.analysisQuery(sections);
        Lexicon.history.set(player.id, rawtext);
    }
    ;
    analysisQuery(request) {
        const entry = request[0];
        const detail = [];
        const rootTags = Lexicon.material.map(info => info[1].root);
        const norm = new Map(Lexicon.material);
        const strictQuery = norm.get(entry);
        const strictText = norm.get(entry)?.intel;
        if (strictQuery && strictQuery.code)
            detail.push(strictQuery?.code(this.player, request.slice(1)));
        if (strictText)
            detail.push(...strictText);
        else
            detail.push(...this.rootTagQuery(false, entry, rootTags, request));
        if (detail.length == 0)
            detail.push(...this.rootTagQuery(true, entry, rootTags, request));
        if (detail.length == 0)
            detail.push(ReplyMessages.unknown_paper);
        if (detail.length >= 5)
            this.output.rawtext?.push(ReplyMessages.obtain_paper, ...detail);
        else
            this.output.rawtext?.push(...detail);
    }
    ;
    rootTagQuery(type, input, tags, rawtexts) {
        const sample = Lexicon.material.map(info => info[1]);
        const detect = [];
        const output = [];
        tags.forEach((tag, index) => {
            const target = sample[index];
            const title = { text: '§q§l' + target.root.join(' - ') + '§r\n\n' };
            const finale = { text: '\n=-=-=-=-=-=-=-=-=-=\n' };
            const confine = target.confine ?? 0.25;
            const proximity = Lexicon.Correlation(input, target.root.join('*'), tag);
            switch (type) {
                case true:
                    if (proximity >= confine)
                        target.only
                            ? detect.push([target, proximity])
                            : output.push(title, ...target.intel, finale);
                    break;
                default:
                    if (new Set(tag).has(input))
                        target.only
                            ? detect.push([target, proximity])
                            : output.push(title, ...target.intel, finale);
                    break;
            }
        });
        if (detect.length == 0)
            return output;
        else {
            const detectMap = detect.map(info => info[0].priority ?? 0 * info[1]);
            const maxPriority = Math.max(...detectMap);
            const index = detectMap.indexOf(maxPriority);
            const randomOutput = detect[math_tools.Random({ min: 0, max: detect.length - 1 }, true)][0].intel;
            if (maxPriority == 0)
                return randomOutput;
            else {
                const feedback = detect[index][0].code?.(this.player, rawtexts.slice(1));
                const intelCopy = [...detect[index][0].intel];
                if (feedback)
                    intelCopy.push(feedback);
                return intelCopy;
            }
        }
    }
    ;
    get interface() { return Lexicon.Format(this.output); }
    ;
    static Format(input) {
        const model = Lexicon.material.length;
        const paper = Lexicon.material.map(info => info[1].intel.length).reduce((pre, next) => pre + next);
        const total = Lexicon.material.flatMap(info => info[1].intel).map(info => info?.text?.length ?? 0).reduce((pre, next) => pre + next);
        const template = {
            rawtext: [
                { text: `嗨, 我是${Lexicon.nameTag}, 很高兴遇见你 !\n` },
                { text: '--------------------------------\n' },
                { text: '让我来介绍一个超级棒的[§s 最终档案馆 §r]项目 !\n' },
                { text: '那就是<§d Intention.v2 [ 意图 ] §r>模块 ! 听起来是不是很厉害 ?\n' },
                { text: '它是用§p MinecraftBE §r的§q ServerAPI §r精心打造的哦 !\n' },
                { text: `模块里藏着§s ${model} §r个精巧的组件, 每个都有它的小秘密 !\n` },
                { text: `样本库有§q ${paper} §r个精彩样本, 每一个都独一无二 !\n` },
                { text: `文献规模达到了§u ${total} §r个字, 每一个字都是我们智慧的结晶 !\n` },
                { text: '这些数据会帮助我更快地找到你需要的信息, 就像魔法一样哦 !\n' },
                { text: '--------------------------------\n' },
            ]
        };
        input?.rawtext?.forEach(info => {
            if (info && info.text) {
                info.text = info.text.replace(/(#\$[\^]+\$\#)/g, Lexicon.nameTag);
            }
        });
        if (input && input?.rawtext?.length)
            return input;
        else
            return template;
    }
    ;
    static SendToChat(player, input) {
        input.rawtext?.forEach(info => {
            if (info && info.text) {
                info.text = info.text.replace(/(#\$[\^]+\$\#)/g, Lexicon.nameTag);
            }
        });
        player.sendMessage(input);
    }
    static Correlation(input, type, source) {
        const sample = new Set(source.join('').split(''));
        const stage = [...new Set(input.split(''))];
        let score = 0;
        stage.forEach(node => sample.has(node) ? score++ : 0);
        const count = Math.floor((score / sample.size) * 1000) / 1000;
        const sampleData = '§r | §5' + '总规模:§2 ' + sample.size;
        const countData = '§r | §5' + '匹配度:§2 ' + count;
        const scoreData = '§r | §5' + '相同字:§2 ' + score;
        if (Lexicon.showLog && count != 0)
            console.error('§p' + type + countData + scoreData + sampleData);
        return count;
    }
    ;
}
;
function analysisDynamicProperty(player) {
    if (!native_tools.PlayerInPower(player))
        return Lexicon.SendToChat(player, ReplyMessages.power_lack);
    const options = {
        excludeTypes: ["minecraft:item", "minecraft:xp_orb"]
    };
    const Distance = (entity) => Math.floor(math_tools.Vector.distance(player.location, entity.location));
    const queue = native_tools.EntitysSort(player.dimension, options, (a, b) => Distance(a) - Distance(b), entity => entity.getComponent('minecraft:health'));
    const title = {
        text: "§9§l<§u 动态属性 §9>§r§3操作界面"
    };
    const display = new server_ui.ActionFormData().title(title);
    const Intel = (entity) => {
        return {
            rawtext: [
                { text: '§l' },
                native_tools.EntityTranslate(entity),
                { text: `\n§r§l§9距离: §5${Distance(entity)}` }
            ]
        };
    };
    queue.forEach(entity => display.button(Intel(entity), "textures/项目图标/元素增益"));
    display.show(player).then(option => {
        if (option.selection == undefined || queue.length === 0)
            return;
        const target = queue[option.selection];
        const property = new Map();
        const types = target.getDynamicPropertyIds();
        const values = types.map(type => target.getDynamicProperty(type));
        types.forEach((type, index) => { const args = values[index]; if (args)
            property.set(type, args); });
        const analysis = [...property].sort((a, b) => {
            return a[0].toLowerCase().charCodeAt(0) - b[0].toLowerCase().charCodeAt(0);
        });
        const display = new server_ui.ModalFormData().title(title);
        const text = { text: "请勿随意修改, 以免发生故障" };
        analysis.forEach(type => display.textField(type[0], text, JSON.stringify(type[1])));
        display.show(player).then(option => {
            if (!option.formValues)
                return;
            option.formValues.forEach((data, index) => {
                target.setDynamicProperty(analysis[index][0], JSON.parse(data));
            });
        });
    });
}
;
function analysisRealm(player, text, after) {
    const entry = server.world.getDynamicPropertyIds().filter(node => node.startsWith(`${text}•`)).sort((a, b) => a.length - b.length);
    const state = entry.map(node => server.world.getDynamicProperty(node));
    const title = {
        text: "§9<§l " + text + " §r§9>"
    };
    const display = new server_ui.ActionFormData().title(title);
    const mapping = (node) => {
        const analysis = node.split(/•/).map(node => Number(node));
        const anchor = { x: analysis[2] * 16, y: 0, z: analysis[4] * 16 };
        return math_tools.Vector.toString(anchor);
    };
    if (entry.length >= 1)
        entry.forEach((info, index) => display.button('§l§9基准坐标 : §5' + mapping(info) + '\n§9属性值 : §r§u' + state[index]));
    else
        display.button('§4§l未创建§r : §u领域属性§9 -> §r' + text);
    display.show(player).then(option => {
        if (option.canceled || option.selection == undefined)
            return;
        if (entry.length == 0)
            return;
        after(player, { option, entry, state });
    });
}
;
function alterEnergy(player, args) {
    const title = { text: "§9《§u§l 调试 - 星尘能量 §9》§r" };
    const text = { text: "请勿随意修改, 以免发生故障" };
    const plan = { text: `${args.state[args.option.selection ?? 0]}` };
    const prompt = { text: '§c数据类型§r:§u 能量值' };
    const display = new server_ui.ModalFormData().title(title).textField(prompt, text, plan.text);
    display.show(player).then(option => {
        if (!option.formValues)
            return;
        if (native_tools.PlayerInPower(player)) {
            const property = Number(option.formValues[0]) ?? 0;
            server.world.setDynamicProperty(args.entry[args.option.selection ?? 0], property);
        }
        else
            Lexicon.SendToChat(player, ReplyMessages.power_lack);
    });
}
;
function alterMineral(player, args) {
    const title = { text: "§9《§u§l 调试 - 虚岩矿脉 §9》§r" };
    const text = { text: "请勿随意修改, 以免发生故障" };
    const analysis = JSON.parse(`${args.state[args.option.selection ?? 0]}`);
    ;
    const proto_amount = analysis.amount;
    const proto_type = analysis.type;
    const display = new server_ui.ModalFormData().title(title);
    proto_type.forEach(type => display.textField('§c数据类型§r:§u 矿物类型', text, type));
    display.textField('§c数据类型§r:§u 矿物数量', text, proto_amount.toString());
    display.show(player).then(option => {
        if (!option.formValues)
            return;
        if (native_tools.PlayerInPower(player)) {
            const type = option.formValues.slice(0, proto_type.length);
            const amount = option.formValues[proto_type.length].split(',').map(Number);
            server.world.setDynamicProperty(args.entry[args.option.selection ?? 0], JSON.stringify({ type, amount }));
        }
        else
            Lexicon.SendToChat(player, ReplyMessages.power_lack);
    });
}
;
function analysisRuneHurt(player, text) {
    if (!native_tools.PlayerInPower(player))
        return Lexicon.SendToChat(player, ReplyMessages.power_lack);
    const damage = (text.match(/\b\d+(\.\d+)?\b/g)?.map(Number) ?? [1])[0];
    const property = power_property.MergeProperty(power_property.GetProperty(player), { raise_basic_attack: damage });
    const erupt = derived_tools.IsErupt(player);
    const options = {
        excludeTypes: ["minecraft:item", "minecraft:xp_orb", player.typeId],
        excludeFamilies: ['starry']
    };
    const Distance = (entity) => Math.floor(math_tools.Vector.distance(player.location, entity.location));
    const queue = native_tools.EntitysSort(player.dimension, options, (a, b) => Distance(a) - Distance(b), entity => !entity.getComponent('minecraft:is_tamed'));
    const title = {
        text: "§9<§u§l 符文伤害 §9>§r§9操作界面"
    };
    const display = new server_ui.ActionFormData().title(title);
    const Intel = (entity) => {
        return {
            rawtext: [
                { text: '§l' },
                native_tools.EntityTranslate(entity),
                { text: `\n§9距离: §5${Distance(entity)}` }
            ]
        };
    };
    if (queue.length >= 1)
        queue.forEach(entity => display.button(Intel(entity)));
    else
        display.button('§4§l不存在 §c<§9 可以§6<§u 选中 §6>§9的实体 §c>§r');
    display.show(player).then(option => {
        if (option.selection == undefined)
            return;
        if (queue.length == 0)
            return;
        const target = queue[option.selection];
        achieve_plan.RunePowerAttack.BriefCreate(player, target, erupt, property);
    });
}
;
function analysisFissure(player, texts) {
    if (!native_tools.PlayerInPower(player))
        return Lexicon.SendToChat(player, ReplyMessages.power_lack);
    const location = () => {
        const matches = texts.join().match(/-?\b\d+(\.\d+)?\b/g);
        const proto = matches?.map(Number) ?? [0, 512, 0];
        return { x: proto[0] ?? 0, y: proto[1] ?? 512, z: proto[2] ?? 0 };
    };
    const dimension = () => {
        const check = texts[3] ?? '主世界';
        return server.world.getDimension(data_story.dimension_map.get(check) ?? 'minecraft:overworld');
    };
    const location_group = [player.getHeadLocation(), location()];
    const dimension_group = [player.dimension, dimension()];
    const source = { location: player.getHeadLocation(), dimension: player.dimension };
    server.system.runTimeout(() => player.playSound("ambient.weather.thunder"), 100);
    server.system.runTimeout(() => player.playSound("ambient.weather.thunder"), 10);
    server.system.runTimeout(() => derived_tools.NumberParticleDisplay(source, 4, math_tools.Vector.CONSTANT_ZERO), 15);
    server.system.runTimeout(() => derived_tools.NumberParticleDisplay(source, 3, math_tools.Vector.CONSTANT_ZERO), 35);
    server.system.runTimeout(() => derived_tools.NumberParticleDisplay(source, 2, math_tools.Vector.CONSTANT_ZERO), 55);
    server.system.runTimeout(() => derived_tools.NumberParticleDisplay(source, 1, math_tools.Vector.CONSTANT_ZERO), 75);
    server.system.runTimeout(() => derived_tools.NumberParticleDisplay(source, 0, math_tools.Vector.CONSTANT_ZERO), 95);
    server.system.runTimeout(() => achieve_plan.MistySeaFissure.Create(player.id, 30, { location_group, dimension_group }), 80);
}
;
function analysisBiome(player, text) {
    const dimension = player.dimension;
    const biome = data_story.biome_map.get(text);
    if (!biome)
        return ReplyMessages.unknown_biome;
    const biomeLocation = dimension.findClosestBiome(player.location, biome);
    if (biomeLocation) {
        const feedback = [
            { text: `${Lexicon.nameTag}找到你说的群系了哦 ！\n\n` },
            { text: `§n生态群系§r :§u§l ${biome}§r\n\n` },
            { text: `§q群系坐标§r :§s§l ${math_tools.Vector.toString(biomeLocation)}§r\n\n` },
            { text: `${Lexicon.nameTag}已经帮你添加好<§9§l 传送锚点 §r>了哦 ！\n` },
        ];
        const anchor = JSON.stringify({ location: math_tools.Vector.floor(biomeLocation), dimension: dimension.id });
        player.setDynamicProperty('road_sign:' + text, anchor);
        return { rawtext: feedback };
    }
    else
        return ReplyMessages.unknown_biome;
}
;
function Window(player, content) {
    const title = { text: "§9《§u§l §r" + LexiconData.nameTag + "§u§l百科 §9》§r" };
    const container = player.getComponent('minecraft:inventory')?.container;
    const typeID = container?.getItem(player.selectedSlotIndex)?.typeId;
    const defaultText = !content ? typeID : undefined;
    const display = new server_ui.ModalFormData().title(title).textField(Lexicon.Format(content), ReplyMessages.ask_for_task, defaultText);
    if (content?.rawtext) {
        if (JSON.stringify(content).length < 72)
            player.sendMessage(content);
        else
            display.show(player).then(option => {
                if (option.canceled || !option.formValues)
                    return;
                Window(player, new Lexicon(player, option.formValues[0]).interface);
            });
    }
    else
        display.show(player).then(option => {
            if (option.canceled || !option.formValues)
                return;
            Window(player, new Lexicon(player, option.formValues[0]).interface);
        });
}
;
function GameHelpTitle(source, title) {
    if (source instanceof server.Entity) {
        title.rawtext?.push({ text: '§9<§l ' }, native_tools.EntityTranslate(source), { text: ' §r§9>§r' });
    }
    else if (source instanceof server.Block) {
        title.rawtext?.push({ text: '§9<§l ' }, native_tools.BlockTranslate(source), { text: ' §r§9>§r' });
    }
    else if (source instanceof server.ItemStack) {
        title.rawtext?.push({ text: '§9<§l ' }, native_tools.ItemTranslate(source), { text: ' §r§9>§r' });
    }
}
;
function GameHelpShow(player, title, text) {
    new server_ui.ActionFormData()
        .title(title)
        .body(text)
        .button('§4§l关闭§r')
        .button('§9§l导出§r')
        .show(player)
        .then(result => {
        if (result.canceled || result.selection == 0)
            return;
        player.sendMessage({
            rawtext: [
                { text: '\n=-=-=-=-=-=-=-=-=-=\n' },
                title,
                { text: '\n\n' },
                text
            ]
        });
    });
}
;
function GameHelp(player, source) {
    const title = { rawtext: [] };
    const text = { rawtext: [] };
    const query = new Lexicon(player, source.typeId).interface;
    GameHelpTitle(source, title);
    text.rawtext?.push(query);
    GameHelpShow(player, title, text);
}
;
function analysisTrophy(player, option, entry) {
    if (option.selection == undefined)
        return;
    const container = player.getComponent('inventory')?.container;
    const select = entry[option.selection][1];
    if (!container)
        return;
    if (select.before && !select.before(player))
        return player.onScreenDisplay.setTitle([
            { text: `§4§l条件不满足\n无法完成任务\n§6< §u` },
            { text: entry[option.selection][0] },
            { text: '§6 >§r' }
        ]);
    if (select.attrition && !native_tools.CheckItemStack(container, select.attrition))
        return player.onScreenDisplay.setTitle([
            { text: `§4§l物品数量不足\n无法完成任务\n§p< §u` },
            { text: entry[option.selection][0] },
            { text: '§6 >§r' }
        ]);
    select.attrition?.forEach(item => native_tools.DeleteItemStack(container, item));
    if (select.reward)
        select.reward.forEach(item => container.addItem(item));
    if (select.onDone)
        select.onDone.forEach(info => player.addTag(info));
    if (select.prompt)
        derived_tools.PlayPrompt(player, select.prompt);
    if (select.after)
        select.after(player);
    player.onScreenDisplay.setTitle([
        { text: `§6§l恭喜你完成任务\n§d< §9` },
        { text: entry[option.selection][0] },
        { text: '§d >§r' }
    ]);
    player.spawnParticle('constant:fireworks_fireball_rune_orange', player.getHeadLocation());
    player.spawnParticle('constant:fireworks_paper_rune_orange', player.getHeadLocation());
    player.playSound('firework.twinkle');
}
;
function Trophy(player, title, data) {
    if (!achieve_plan.ControlEventTrigger.EntityToken('Trophy', player, 200))
        return player.onScreenDisplay.setTitle('§l§c请稍后再试!');
    const display = new server_ui.ActionFormData().title(title);
    const tags = new Set(player.getTags());
    const entry = [...data].filter(info => info[1]?.rely?.every(tag => tags.has(tag)) ?? true)
        .filter(info => !info[1]?.onDone?.every(tag => tags.has(tag)) ?? false);
    if (entry.length == 0)
        return player.onScreenDisplay.setTitle({ text: '§l§m没有了哦, 什么都没有了啦...' });
    entry.forEach(info => display.button({ rawtext: info[1].refer }, info[1].texture));
    display.show(player).then(option => analysisTrophy(player, option, entry));
}
;
;
